package com.gsafety.wellsfort.service.course;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.gsafety.wellsfort.common.context.LoginContextUtil;
import com.gsafety.wellsfort.common.enums.RoleGroupEnum;
import com.gsafety.wellsfort.common.util.ApiResponse;
import com.gsafety.wellsfort.common.util.DateUtil;
import com.gsafety.wellsfort.common.util.ResultCode;
import com.gsafety.wellsfort.dao.course.*;
import com.gsafety.wellsfort.dao.knowledge.*;
import com.gsafety.wellsfort.dao.organization.ClassDAO;
import com.gsafety.wellsfort.dao.organization.StudentDAO;
import com.gsafety.wellsfort.dao.security.AdminDAO;
import com.gsafety.wellsfort.dao.security.RoleDAO;
import com.gsafety.wellsfort.domain.dto.course.ExamFinishPreviewDTO;
import com.gsafety.wellsfort.domain.dto.course.ExamPublishDTO;
import com.gsafety.wellsfort.domain.dto.course.ExamPublishQueryDTO;
import com.gsafety.wellsfort.domain.dto.course.WorkFinishPreviewDTO;
import com.gsafety.wellsfort.domain.dto.ids.ExamPublishIdDTO;
import com.gsafety.wellsfort.domain.model.course.*;
import com.gsafety.wellsfort.domain.model.knowledge.ExamPaper;
import com.gsafety.wellsfort.domain.model.knowledge.Work;
import com.gsafety.wellsfort.domain.model.organization.Class;
import com.gsafety.wellsfort.domain.model.organization.Student;
import com.gsafety.wellsfort.domain.model.security.Admin;
import com.gsafety.wellsfort.domain.model.security.Role;
import com.gsafety.wellsfort.domain.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.map.HashedMap;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
@Slf4j
public class ExamPublishService {
    @Autowired(required = false)
    CourseDAO courseDAO;

    @Autowired(required = false)
    LessonPeriodDAO lessonPeriodDAO;

    @Autowired(required = false)
    CourseRangeDAO courseRangeDAO;

    @Autowired(required = false)
    CoursewareDAO coursewareDAO;

    @Autowired(required = false)
    TeachingMaterialDAO materialDAO;

    @Autowired(required = false)
    TeachingAidDAO teachingAidDAO;

    @Autowired(required = false)
    WorkDAO workDAO;

    @Autowired(required = false)
    AdminDAO adminDAO;

    @Autowired(required = false)
    ExamPaperDAO examPaperDAO;

    @Autowired(required = false)
    StudentExamDAO studentExamDAO;

    @Autowired(required = false)
    ExamPublishDAO examPublishDAO;

    @Autowired(required = false)
    ExamPublishRangeDAO examPublishRangeDAO;

    @Autowired(required = false)
    LearningProgressDAO learningProgressDAO;

    @Autowired(required = false)
    StudentDAO studentDAO;
    @Autowired(required = false)
    ClassDAO classDAO;


    @Autowired(required = false)
    private RoleDAO roleDAO;

    @Autowired(required = false)
    private ExamQuestionDAO examQuestionDAO;

    public ApiResponse<ExamPublishDTO> publishStuExam(ExamPublishDTO examPublishDTO){
        ApiResponse<ExamPublishDTO> apiResponse=null;
        try{
            ExamPublish exmPublish=new ExamPublish();
            BeanUtils.copyProperties(examPublishDTO,exmPublish);
            if(examPublishDTO.getPublishTime()!=null){
                exmPublish.setPublishTime(DateUtil.parseTime(examPublishDTO.getPublishTime()));
            }
            if(LoginContextUtil.getAdmin()!=null){
                //状态设置为已发布
                exmPublish.setPublishState(Byte.parseByte("1"));
                exmPublish.setPublishUserId(LoginContextUtil.getAdmin().getId());
            }else{
                return ApiResponse.error(ResultCode.ERROR.getCode(),"管理员未登录!");
            }
            if(examPublishDTO.getExamId()!=null){
                Map<String,Object> questionParam=new HashedMap();
                questionParam.put("examId",examPublishDTO.getExamId());
                List<QuestionVO> questionList=examQuestionDAO.selectByParam(questionParam);
                if (questionList.size()<=0){
                    return ApiResponse.error(ResultCode.ERROR.getCode(),"该试卷没有题目，不能发布!");
                }
            }
            //作业发布编辑
            if(examPublishDTO.getId()!=null){
                //清除课程范围
                examPublishRangeDAO.deleteByExamPublishId(examPublishDTO.getId());
                //清除学生作业
                studentExamDAO.deleteByExamPublishId(examPublishDTO.getId());
                //更新发布记录
                ExamPublish examPublishDB=examPublishDAO.selectByPrimaryKey(examPublishDTO.getId());
                examPublishDB.setExamId(examPublishDTO.getExamId());
                if(examPublishDTO.getPublishTime()!=null){
                    Date publicDate=DateUtil.parseTime(examPublishDTO.getPublishTime());
                    examPublishDB.setPublishTime(publicDate);
                }
                examPublishDAO.updateByPrimaryKeySelective(examPublishDB);
            }else{
                exmPublish.setPublishNums(1);
                exmPublish.setFinishNums(0);
                examPublishDAO.insertSelective(exmPublish);
                examPublishDTO.setId(exmPublish.getId());
            }
            //更新发布次数
            ExamPaper examPaperDB=examPaperDAO.selectByPrimaryKey(examPublishDTO.getExamId());
            if(examPaperDB!=null)
            {
                if(examPaperDB.getPublicTimes()==null){
                    examPaperDB.setPublicTimes(0);
                }
                examPaperDB.setPublicTimes(examPaperDB.getPublicTimes()+1);
                examPaperDAO.updateByPrimaryKeySelective(examPaperDB);
            }
            //课程范围,如果是平台用户
            Integer[] classIds;
            if(examPublishDTO.getIsPlatform()!=null&&examPublishDTO.getIsPlatform()==1){
                classIds=(Integer[]) classDAO.selectAll().toArray();
            }else{
                classIds=examPublishDTO.getClassIds();
            }
            StudentExam stuExam=null;
            Class cls= null;
            List<Student> stuList;
            for(Integer clsId:classIds){
                cls=classDAO.selectByPrimaryKey(clsId);
                ExamPublishRange record=ExamPublishRange.builder().examPublishId(examPublishDTO.getId())
                        .schoolId(cls.getSchoolId())
                        .classId(clsId)
                        .creator(LoginContextUtil.getAdmin().getId())
                        .createTime(new Date()).build();
                examPublishRangeDAO.insert(record);
                //根据班级Id下的学生,生成试卷
                Map<String,Object>stuParam=new HashedMap();
                stuParam.put("classId",clsId);
                stuList=studentDAO.listQuery(stuParam);
                for(Student stu:stuList){
                    stuExam =new StudentExam();
                    stuExam.setClassId(clsId);
                    stuExam.setStudentId(stu.getId());
                    stuExam.setCourseId(exmPublish.getCourseId());
                    stuExam.setFinishState((byte)0);
                    stuExam.setPublishTime(exmPublish.getPublishTime());
                    stuExam.setLessonPeriodId(exmPublish.getLessonPeriodId());
                    stuExam.setExamId(exmPublish.getExamId());
                    stuExam.setExamPublishId(exmPublish.getId());
                    stuExam.setIsPassed((byte)0);
                    studentExamDAO.insert(stuExam);
                }
            }

            apiResponse=ApiResponse.success(examPublishDTO);
        }catch (Exception e){
            apiResponse=ApiResponse.error(ResultCode.PUBLISH_WORK_ERROR,e.getMessage());
            e.printStackTrace();
        }


        return apiResponse;
    }
    public ApiResponse<ExamPublishIdDTO> cancelExamPublish(ExamPublishIdDTO examPublishEditDTO){
        ApiResponse apiResponse=null;
        try{
            ExamPublish examPublishDB= examPublishDAO.selectByPrimaryKey(examPublishEditDTO.getId());
            if(examPublishDB!=null){
                examPublishDB.setPublishState((byte)0);
                examPublishDAO.updateByPrimaryKeySelective(examPublishDB);
            }
/*            if(examPublishEditDTO.getId()!=null){
                //清除课程范围
                examPublishRangeDAO.deleteByExamPublishId(examPublishEditDTO.getId());
                //清除学生试卷
                studentExamDAO.deleteByExamPublishId(examPublishEditDTO.getId());
                //更新发布次数
                ExamPublish examPublishDB= examPublishDAO.selectByPrimaryKey(examPublishEditDTO.getId());
                examPublishDB.setPublishNums(examPublishDB.getPublishNums()+1);
                examPublishDAO.updateByPrimaryKeySelective(examPublishDB);
            }*/
            apiResponse=ApiResponse.success();
        }catch (Exception e){
            apiResponse=ApiResponse.error(ResultCode.PUBLISH_WORK_ERROR,e.getMessage());
            e.printStackTrace();
        }
        return apiResponse;
    }
    public ApiResponse<ExamPublishIdDTO> againEaxamPublish(ExamPublishIdDTO workPublishEditDTO){
        ApiResponse<ExamPublishIdDTO> apiResponse=null;
        try{
            ExamPublish examPublishDB= examPublishDAO.selectByPrimaryKey(workPublishEditDTO.getId());
            if(examPublishDB!=null){
                examPublishDB.setPublishState((byte)1);
                examPublishDAO.updateByPrimaryKeySelective(examPublishDB);
            }
/*            if(workPublishEditDTO.getId()!=null){
                //清除课程范围
                workPublishRangeDAO.deleteByWorkPublishId(workPublishEditDTO.getId());
                //清除学生作业
                studentWorkDAO.deleteByWorkPublishId(workPublishEditDTO.getId());
                //更新发布次数
                WorkPublish workPublishDB= workPublishDAO.selectByPrimaryKey(workPublishEditDTO.getId());
                workPublishDB.setPublishNums(workPublishDB.getPublishNums()+1);
                workPublishDAO.updateByPrimaryKeySelective(workPublishDB);
            }*/
            apiResponse=ApiResponse.success();
        }catch (Exception e){
            apiResponse=ApiResponse.error(ResultCode.PUBLISH_WORK_ERROR,e.getMessage());
            e.printStackTrace();
        }
        return apiResponse;
    }
    public ApiResponse<ExamPublishEditVO> getPublicExamDetail(ExamPublishIdDTO examPublishIdDTO){
        Integer id=examPublishIdDTO.getId();
        ApiResponse<ExamPublishEditVO> apiResponse=null;
        try{
            ExamPublish examPublish= examPublishDAO.selectByPrimaryKey(id);
            String examName="";
            if(examPublish.getExamId()!=null){
                ExamPaper examPaper= examPaperDAO.selectByPrimaryKey(examPublish.getExamId());
                examName=examPaper.getExamTitle();
            }
            ExamPublishEditVO examPublishEditVO=ExamPublishEditVO.builder().examName(examName).build();
            BeanUtils.copyProperties(examPublish,examPublishEditVO);
            apiResponse=ApiResponse.success(examPublishEditVO);
        }catch (Exception e){
            apiResponse=ApiResponse.error();
            e.printStackTrace();
        }
        return apiResponse;
    }
    public ApiResponse<List<ExamPublishVO>> listPublishExam(ExamPublishQueryDTO dtoParams) {
        ApiResponse<List<ExamPublishVO>> apiResponse=null;
        if (LoginContextUtil.getAdmin() != null) {
            //添加数据权限判断
            Admin admin = LoginContextUtil.getAdmin();
            if (admin == null) {
                return ApiResponse.error(ResultCode.INVALID_PARAM);
            }
            List<Integer> ids = new ArrayList<>();
            List<Admin> adminList = new ArrayList<>();
            List<Role> list = roleDAO.selectRoleByAdminId(admin.getId());
            if (list != null && list.size() > 0) {
                if (RoleGroupEnum.SCHOOL_ADMIN.getCode().equals(list.get(0).getRoleGroup().intValue())) {
                    //学校管理员,查看学校创建
                    adminList = adminDAO.selectBySchoolId(admin.getSchoolId());
                } else if (RoleGroupEnum.TEACHER_ADMIN.getCode().equals(list.get(0).getRoleGroup().intValue())) {
                    //教师平台，查看自己创建
                    adminList.add(admin);
                }
                for (Admin ad : adminList) {
                    ids.add(ad.getId());
                }
            }
            dtoParams.setIds(ids);
        }
        Page page= PageHelper.startPage(dtoParams.getPageNo(), dtoParams.getPageSize());
        List<ExamPublishVO> voList= examPublishDAO.selectByParam(dtoParams);
        Admin admin;
        Course course;
        LessonPeriod lessonPeriod;
        for(ExamPublishVO vo:voList){
            if(vo.getPublishUserId()!=null){
                admin=adminDAO.selectByPrimaryKey(vo.getPublishUserId());
                if(admin!=null)vo.setPublishUserName(admin.getName());
            }
            if(vo.getPublishNums()!=null){
                Integer publishNum=studentExamDAO.countPublishNum(vo.getId());
                vo.setPublishNums(publishNum);
                ExamPublish wp=examPublishDAO.selectByPrimaryKey(vo.getId());
                wp.setPublishNums(publishNum);
                examPublishDAO.updateByPrimaryKeySelective(wp);
            }
            vo.setFinishNums(studentExamDAO.countPublishFinishNum(vo.getPublishUserId(),null,1));
            if(vo.getCourseId()!=null){
                course=courseDAO.selectByPrimaryKey(vo.getCourseId());
                if(course!=null){
                    vo.setCourseName(course.getName());
                }
            }
            if(vo.getLessonPeriodId()!=null){
                lessonPeriod=lessonPeriodDAO.selectByPrimaryKey(vo.getLessonPeriodId());
                if(lessonPeriod!=null){
                    vo.setLessonPeriodName(lessonPeriod.getName());
                }
            }
        }
        PageInfo pageInfo= new PageInfo(page);
        pageInfo.setList(voList);
        apiResponse=ApiResponse.success(voList,(int)pageInfo.getTotal());
        return apiResponse;
    }

    public ApiResponse<ExamFinishPreviewVO> finishPreview(ExamFinishPreviewDTO examFinishPreviewDTO){
        ApiResponse<ExamFinishPreviewVO> apiResponse=null;
        try{
            ExamFinishPreviewVO examFinishPreviewVO= ExamFinishPreviewVO.builder().build();
            Page page= PageHelper.startPage(examFinishPreviewDTO.getPageNo(), examFinishPreviewDTO.getPageSize());
            List<StudentExamFinishRecordVO> studentExamFinishRecordVOList =studentExamDAO.selectByFinishPreviewDTO(examFinishPreviewDTO);
            List<Map<String,Object>> classNameList=new ArrayList<Map<String,Object>>();
            Class cls;
            Student stu;
            Set<Integer> clsSet=new HashSet<Integer>();
            //处理学生信息
            for(StudentExamFinishRecordVO recordVO : studentExamFinishRecordVOList){
                if(recordVO.getClassId()!=null){
                    clsSet.add(recordVO.getClassId());
                    cls=classDAO.selectByPrimaryKey(recordVO.getClassId());
                    if(cls!=null)recordVO.setClassName(cls.getName());
                }
                if(recordVO.getStudentId()!=null){
                    stu=studentDAO.selectByPrimaryKey(recordVO.getStudentId());
                    if(stu!=null)recordVO.setStudentName(stu.getName());
                }
                if(recordVO.getIsPassed()==null||recordVO.getIsPassed()==0){
                    recordVO.setIsPassedText("不通过");
                }else if(recordVO.getIsPassed()==1){
                    recordVO.setIsPassedText("通过");
                }
            }
            //处理班级
            for(Integer clsId:clsSet){
                Map<String,Object> classNameMap=new HashMap<String,Object>();
                cls=classDAO.selectByPrimaryKey(clsId);
                classNameMap.put("classId",clsId);
                if(cls!=null)classNameMap.put("className",cls.getName());
                classNameList.add(classNameMap);
            }
            examFinishPreviewVO.setClassNameList(classNameList);
            //处理作业相关信息
            if(studentExamFinishRecordVOList.size()>0){
                StudentExamFinishRecordVO recordVO= studentExamFinishRecordVOList.get(0);
                if(recordVO.getExamTitle()!=null)examFinishPreviewVO.setExamTitle(recordVO.getExamTitle());
                if(recordVO.getExamId()!=null){
                    examFinishPreviewVO.setExamId(recordVO.getExamId());
                }
                if(recordVO.getCourseId()!=null){
                    Course course=courseDAO.selectByPrimaryKey(recordVO.getCourseId());
                    if(course!=null)examFinishPreviewVO.setCourseName(course.getName());
                }
                if(recordVO.getLessionPeriodId()!=null){
                    LessonPeriod lessonPeriod=lessonPeriodDAO.selectByPrimaryKey(recordVO.getLessionPeriodId());
                    if(lessonPeriod!=null)examFinishPreviewVO.setCourseName(lessonPeriod.getName());
                }
            }
            examFinishPreviewVO.setStudentExamFinishRecordVOList(studentExamFinishRecordVOList);

            PageInfo pageInfo= new PageInfo(page);
            pageInfo.setList(studentExamFinishRecordVOList);
            apiResponse=ApiResponse.success(examFinishPreviewVO,(int) pageInfo.getTotal());
        }catch (Exception e){
            e.printStackTrace();
            log.error(e.getMessage());
            apiResponse=ApiResponse.error(ResultCode.ERROR,e.getMessage());
        }

        return apiResponse;
    }
}
